package top.lshaci.learning.jsoup;

import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpUtil;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

import java.io.File;
import java.util.concurrent.TimeUnit;

/**
 * FuliGirl
 *
 * @author liangxu
 */
public class FuliGirl {
    static String path = "D:\\fuligirl";

    static String modelsUrl;
    static String modelUrl;
    static String albumUrl;

    public static void main(String[] args) throws Exception {
//        String modelsUrl = "https://fuligirl.top/models";
//        models(modelsUrl);

        // 下载单个模特图片
//        String modelUrl = "https://fuligirl.top/models/104?page=2";
//        model(modelUrl);
/**
 * 441,440,439,438,437,436,435,434,433,432,431,244
 */

        String u = "431,244";
        for (String s : u.split(",")) {
            // 下载模特单个专辑图片
            String albumUr = StrUtil.format("https://fuligirl.top/albums/{}?page=1", s);
            try {
                album(albumUr);
            } catch (Exception e) {
                try {
                    album(albumUrl);
                } catch (Exception e1) {
                    try {
                        album(albumUrl);
                    } catch (Exception e2) {
                        album(albumUrl);
                    }
                }
            }
        }
//        // 下载模特单个专辑图片
//        String albumUr = "https://fuligirl.top/albums/432?page=3";
//        try {
//            album(albumUr);
//        } catch (Exception e) {
//            try {
//                album(albumUrl);
//            } catch (Exception e1) {
//                try {
//                    album(albumUrl);
//                } catch (Exception e2) {
//                    album(albumUrl);
//                }
//            }
//        }
    }

    /**
     * 下载模特图片的方法
     *
     * @param modelsUrl 模特图片页面的URL
     * @throws Exception 抛出异常，处理网络连接等异常情况
     */
    private static void models(String modelsUrl) throws Exception {
        // 设置全局模特URL
        FuliGirl.modelsUrl = modelsUrl;
        // 连接到模特图片页面并获取页面内容
        Document modelsPage = Jsoup.connect(modelsUrl).get();
        // 选择所有模特的容器元素
        Elements models = modelsPage.select("div.relative");
        // 遍历每个模特容器，下载模特图片
        for (Element model : models) {
            // 获取模特名称
            String modelName = model.selectFirst("img[title]").attr("title");
            // 构建模特图片的保存路径
            String modelPath = path + "\\" + modelName;
            // 检查模特目录是否已存在，若存在则跳过该模特
            boolean exists = mkdir(modelPath);
            if (exists) {
                continue;
            }
            // 获取模特图片的URL
            String modelUrl = model.selectFirst("a").attr("href");
            // 下载并保存模特图片
            model(modelUrl);
        }
        // 寻找并处理分页，若存在下一页，则继续下载
        Element next = modelsPage.selectFirst("a[rel='next']");
        if (next == null) {
            return;
        }
        // 递归下载下一页的模特图片
        models(next.attr("href"));
    }

    /**
     * 下载并保存模特图片。
     *
     * @param modelUrl 模特图片的来源网址。
     * @throws Exception 如果发生网络错误或IO异常，则抛出异常。
     */
    private static void model(String modelUrl) throws Exception {
        // 设置模特图片的来源网址
        FuliGirl.modelUrl = modelUrl;
        // 连接到模特页面并解析
        Document modelPage = Jsoup.connect(modelUrl).get();
        // 创建本地保存路径
        String modelPath = path + "\\" + modelPage.selectFirst("h1").html();
        mkdir(modelPath);
        // 选择所有专辑元素
        Elements albums = modelPage.select("div.relative");
        // 遍历每个专辑，下载并保存图片
        for (Element album : albums) {
            // 获取专辑名称
            String albumName = album.selectFirst("img[title]").attr("title");
            // 拼接本地保存路径
            String albumPath = modelPath + "\\" + albumName;
            // 检查目录是否已存在，若存在则跳过
            boolean exists = mkdir(albumPath);
            if (exists) {
                continue;
            }
            // 获取专辑的详细页面网址
            String albumUrl = album.selectFirst("a").attr("href");
            // 递归处理专辑页面
            album(albumUrl);
        }
        // 寻找下一个页面的链接，若存在则继续下载
        Element next = modelPage.selectFirst("a[rel='next']");
        if (next == null) {
            return;
        }
        // 递归下载下一个页面
        model(next.attr("href"));
    }

    /**
     * 下载指定专辑中的所有图片。
     *
     * @param albumUrl 专辑的网址。
     * @throws Exception 如果发生网络错误或IO错误则抛出异常。
     */
    private static void album(String albumUrl) throws Exception {
        // 设置专辑的URL
        FuliGirl.albumUrl = albumUrl;
        // 获取专辑页面
        Document albumPage = Jsoup.connect(albumUrl).get();
        String modelPath = albumPage.selectFirst("a.m-1.p-1").html();
        String albumPath = path + "\\" + modelPath + "\\" + albumPage.selectFirst("h1").html();
        // 创建本地存储目录
        mkdir(albumPath);
        // 选择所有图片元素
        Elements imgs = albumPage.select("img.block.my-1");
        // 遍历图片元素，并下载图片
        for (Element img : imgs) {
            // 获取图片源地址
            String imgSrc = img.attr("src");
            // 下载图片
            download(imgSrc, albumPath, img.attr("title") + ".jpg");
        }
        // 寻找下一个专辑页面的链接
        Element next = albumPage.selectFirst("a[rel='next']");
        if (next == null) {
            // 如果没有下一个页面，则结束递归
            return;
        }
        // 递归下载下一个专辑页面的图片
        album(next.attr("href"));
    }


    /**
     * 下载图片到指定文件夹。
     *
     * @param imgUrl    图片的URL地址
     * @param albumPath 存储图片的文件夹路径
     * @param imgName   图片在文件夹中的名称
     * @throws Exception 如果下载过程中发生错误，则抛出异常
     */
    private static void download(String imgUrl, String albumPath, String imgName) throws Exception {
        // 打印下载任务的信息
        System.err.println(StrUtil.format("modelsUrl: {}\r\n modelUrl: {}\r\n albumUrl: {}\r\n  imgName: {}\r\n", modelsUrl, modelUrl, albumUrl, imgName));
        // 拼接图片的本地路径
        String imgPath = albumPath + "\\" + imgName;
        // 创建File对象，替换路径中的通配符
        File imgFile = new File(imgPath.replace("?", ""));
        // 如果图片文件已存在，则直接返回
        if (imgFile.exists()) {
            return;
        }
        // 下载图片
        HttpUtil.downloadFile(imgUrl, imgFile);
        // 等待500毫秒，避免下载速度过快导致的问题
        TimeUnit.MILLISECONDS.sleep(1000);
    }

    /**
     * 创建目录
     *
     * @param dirPath 目录路径字符串，可能包含通配符?，每个?将被替换为空字符串
     * @return 如果目录创建成功，则返回false；如果目录已存在或创建失败，则返回true
     */
    private static boolean mkdir(String dirPath) {
        // 替换路径中的通配符?后尝试创建目录，返回值取反以符合逻辑要求
        return !new File(dirPath.replace("?", "")).mkdirs();
    }
}
